package org.softmed.neodatis.util;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.softmed.reflection.utils.FieldInfo;
import org.softmed.reflection.utils.ReflectionUtil;

public class PrimaryKeyManager {

	// static String defaultPrimaryKeyFieldName = "id";

	Map<Class, FieldInfo> keys = new HashMap<Class, FieldInfo>();

	List<Class> dontUseInheritedPKeys = new ArrayList<Class>();

	ReflectionUtil util = new ReflectionUtil();

	public void registerPrimaryKey(Class type, String fieldName)
			throws Throwable {
		FieldInfo info = util.getFieldInfo(type, fieldName);

		keys.put(type, info);
		dontUseInheritedPrimaryKeys(type);
	}

	public void dontUseInheritedPrimaryKeys(Class type) {
		dontUseInheritedPKeys.add(type);
	}

	public FieldInfo getPrimaryKeyInfo(Class type) throws Throwable {
		FieldInfo info = keys.get(type);
		if (info != null)
			return info;

		if (dontUseInheritedPKeys.contains(type))
			return null;

		Class parent = type.getSuperclass();
		if (parent != null && parent != Object.class)
			return getPrimaryKeyInfo(parent);

		return null;

		// return getDefaultPrimaryKeyInfo(type);
	}

	// public FieldInfo getDefaultPrimaryKeyInfo(Class type) throws Throwable {
	// Method getter = util.getGetter(type, defaultPrimaryKeyFieldName);
	//
	// if (getter == null)
	// return null;
	//
	// if (getter.getReturnType() != Long.class)
	// return null;
	// Method setter = util.getSetter(type, Long.class,
	// defaultPrimaryKeyFieldName);
	// FieldInfo finfo = new FieldInfo(defaultPrimaryKeyFieldName, getter,
	// setter, Long.class);
	// return finfo;
	// }

	public Map<Class, FieldInfo> getKeys() {
		return keys;
	}

	public PrimaryKey getProperPrimaryKey(Class type, String id)
			throws Throwable {
		FieldInfo pkey = getPrimaryKeyInfo(type);
		Object key = null;
		// if (pkey == null)
		// pkey = util.getFieldInfo(type, defaultPrimaryKeyFieldName);

		if (pkey == null)
			return null;

		if (pkey.getType() == String.class)
			return new PrimaryKey(pkey.getName(), id);

		if (pkey.getType() == Long.class)
			return new PrimaryKey(pkey.getName(), Long.valueOf(id));

		if (pkey.getType() == Integer.class)
			return new PrimaryKey(pkey.getName(), Integer.valueOf(id));

		return null;
	}

}
